home *** CD-ROM | disk | FTP | other *** search
- /*
- * REALbasic-Plugin for hiding the Menu Bar (including the rounded corners
- * as well as other floating objects, like the Control Strip and
- * the detachable Application Floater from OS 8.5 and beyond).
- *
- * Note that it is OS 8.5-savvy, and also automatically takes care
- * of restoring the MenuBar when the app quits unexpectedly (due to
- * a crash) or when the app is suspended (brought to the background).
- * Other similar plugins may not have these important features!
- * (I'm not trying to sell you something here, I just want to help
- * you make your software a bit safer :-)
- *
- * This code is freeware, you may use and extend it as you like.
- *
- * The enclosed project file was created using CodeWarrior Pro 3.
- * To compile it, you also need the "HideMenubarEtc" sample code
- * from Apple. It can be downloaded by logging onto
- * http://www.apple.com/developer
- * and searching for "HideMenubarEtc". You should find a file
- * with exactly that name available for downloading (it's part
- * of the Toolbox Sample Code).
- * To create the plugin, you need to make the target "Create Fat Plugin".
- *
- * It was written on March 8, 99 by Thomas Tempelmann.
- * More RB-related stuff can be found here: <http://www.tempel.org/rb>
- *
- * Updated May 3, 99 for v1.1:
- * - added the ability to set a background window (using SetBackgroundWindow)
- * that then will not brought to the front when the user clicks on it.
- * - fixed a bug that caused PPC plugins to crash under OS 8.5 and beyond
- *
- * Enjoy and contribute!
- */
-
- #include <stdlib.h>
- #include <MixedMode.h>
- #include <SetupA4.h>
- #include <ControlStrip.h>
-
- #ifdef powerc
- #include "68K Interface.h"
- #endif
-
- #include "MenusLib Interface.h"
- #include "ShowHideMenubar.h"
- #include "ShowHideCorners.h"
- #include "rb_plugin.h"
-
-
- const ProcInfoType wneProcInfo =
- kPascalStackBased |
- RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) |
- STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) |
- STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(EventRecord*))) |
- STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(UInt32))) |
- STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(RgnHandle)));
-
- #ifdef powerc
- typedef UniversalProcPtr wneProc;
- #else
- typedef pascal Boolean (*wneProc) (short eventMask, EventRecord* theEvent, UInt32 sleep, RgnHandle mouseRgn);
- #endif
-
- far static Boolean ControlStripExists, HasOS85MenuMgr, qdSet, gCSIsHidden, gMBIsHidden;
- far static UniversalProcPtr gOldExitToShell, gNewExitToShell, gNewWNE;
- far static wneProc gOldWNE;
- far static WindowPtr gBackgroundWindow;
- far QDGlobals qd;
-
-
- static void initQD ();
- static void deInstall ();
-
-
- //
- // taken from Universal Headers 3.2:
- //
- // Routines available in Mac OS 8.5 and later
- EXTERN_API(Boolean) IsMenuBarVisible (void);
- EXTERN_API(void) ShowMenuBar (void);
- EXTERN_API(void) HideMenuBar (void);
-
-
- static long isMenuBarVisible ()
- {
- if (HasOS85MenuMgr) {
- return MenusLibIsMenuBarVisible ();
- } else {
- return GetMBarHeight () > 1; // due to a Technote from Apple, a menu bar hight of 1 is to be considered a hidden menu
- }
- }
-
- static void hideMenuBar ()
- {
- gMBIsHidden = true;
- if (!qdSet) initQD();
- if (HasOS85MenuMgr) {
- MenusLibHideMenuBar ();
- } else {
- SetMBarState (HIDE);
- }
- SetCornersState (HIDE);
- }
-
- static void showMenuBar (void)
- {
- gMBIsHidden = false;
- if (!qdSet) initQD();
- SetCornersState (SHOW);
- if (HasOS85MenuMgr) {
- MenusLibShowMenuBar ();
- } else {
- SetMBarState (SHOW);
- }
- }
-
-
- static void hideControlStrip ()
- {
- if (ControlStripExists) {
- if (!qdSet) initQD();
- gCSIsHidden = true;
- SBShowHideControlStrip (false);
- }
- }
-
- static void showControlStrip ()
- {
- if (ControlStripExists) {
- if (!qdSet) initQD();
- gCSIsHidden = false;
- SBShowHideControlStrip (true);
- }
- }
-
- static long controlStripExists ()
- {
- return ControlStripExists;
- }
-
- static long isControlStripVisible ()
- {
- if (ControlStripExists) {
- return SBIsControlStripVisible ();
- }
- return false;
- }
-
- static void restoreMenuBarEtc ()
- // should be called when app quits
- // (at least when the app is run from inside the RB IDE!)
- {
- deInstall ();
- }
-
- static void setBackgroundWindow (REALwindow wdw)
- {
- if (wdw == NULL) {
- gBackgroundWindow = nil;
- } else {
- if (!qdSet) initQD();
- gBackgroundWindow = REALGetWindowHandle (wdw);
- }
- }
-
-
- REALexport pluginExports[] = {
- { nil, isMenuBarVisible },
- { nil, hideMenuBar },
- { nil, showMenuBar },
- { nil, isControlStripVisible },
- { nil, hideControlStrip },
- { nil, showControlStrip },
- { nil, restoreMenuBarEtc },
- { nil, controlStripExists },
- { nil, setBackgroundWindow },
- };
-
- short pluginExportCode = sizeof(pluginExports) / sizeof(REALexport);
-
- REALmethodDefinition methods[] = {
- {0, "IsMenuBarVisible() as Boolean"},
- {1, "HideMenuBar()"},
- {2, "ShowMenuBar()"},
- {3, "IsControlStripVisible() as Boolean"},
- {4, "HideControlStrip()"},
- {5, "ShowControlStrip()"},
- {6, "RestoreMenuBar()"},
- {7, "ControlStripExists() as Boolean"},
- {8, "SetBackgroundWindow(w as Window)"},
- };
-
-
- static void handleOSEvt (EventRecord *theEvent)
- {
- Boolean suspend = (theEvent->message & 1) == 0;
- if (suspend) {
- if (gMBIsHidden) {
- showMenuBar ();
- if (ControlStripExists && gCSIsHidden) {
- SBShowHideControlStrip (true);
- }
- gMBIsHidden = true;
- }
- } else {
- if (gMBIsHidden) {
- if (ControlStripExists && gCSIsHidden) {
- SBShowHideControlStrip (false);
- }
- hideMenuBar ();
- }
- }
- }
-
- static pascal Boolean wneHook (EventMask eventMask, EventRecord* theEvent, UInt32 sleep, RgnHandle mouseRgn)
- {
- Boolean b = CALL_FOUR_PARAMETER_UPP (gOldWNE, wneProcInfo, eventMask, theEvent, sleep, mouseRgn);
- if (theEvent->what == osEvt && (theEvent->message & 0xFF000000) == 0x01000000) {
- // our RB application is (de)activated -> show/hide the menu bar
- handleOSEvt (theEvent);
- } else if (gBackgroundWindow != nil && theEvent->what == mouseDown) {
- // mouse button was clicked -> check if it is clicked in our background window
- WindowPtr theWin;
- short where = FindWindow (theEvent->where, &theWin);
- if (where == inContent && theWin == gBackgroundWindow) {
- // yes, user clicked into the background window -> disable this event in order to prevent this window to be brought to front
- theEvent->what = nullEvent;
- b = false;
- }
- }
- return b;
- }
-
- static void deInstall ()
- {
- if (gOldExitToShell) SetToolTrapAddress (gOldExitToShell, _ExitToShell);
- gOldExitToShell = nil;
- if (gOldWNE) SetToolTrapAddress ((UniversalProcPtr)gOldWNE, _WaitNextEvent);
- gOldWNE = nil;
- if (gMBIsHidden) {
- showMenuBar ();
- if (gCSIsHidden) showControlStrip ();
- }
- gCSIsHidden = false;
- qdSet = false;
- }
-
- static pascal void quit (void)
- {
- EnterCallback();
- deInstall ();
- ExitCallback();
- ExitToShell ();
- }
-
-
- static void initQD ()
- // called when any of the RB functions here get called the first time
- {
- QDGlobals *orig_qd = (QDGlobals*) (*(Ptr*)LMGetCurrentA5() - offsetof(QDGlobals, thePort));
- qd = *orig_qd;
- qdSet = true;
-
- gBackgroundWindow = nil;
-
- // install a WNE hook so that we are notified when our app gets pushed in
- // the background, so that we can restore the MenuBar for so long.
- gOldWNE = (wneProc) NGetTrapAddress (_WaitNextEvent, 1);
- SetToolTrapAddress (gNewWNE, _WaitNextEvent);
-
- // install a hook onto ExitToShell() in order to restore everything in case the app crashes
- gOldExitToShell = NGetTrapAddress (_ExitToShell, 1);
- SetToolTrapAddress (gNewExitToShell, _ExitToShell);
- }
-
-
- static void init ()
- {
- long gestaltAnswer;
-
- // check for Control Strip
- Gestalt (gestaltControlStripAttr, &gestaltAnswer);
- ControlStripExists = (gestaltAnswer & (1 << gestaltControlStripExists)) != 0;
-
- // check for new Menu Mgr (OS 8.5)
- Gestalt ('menu', &gestaltAnswer);
- HasOS85MenuMgr = gestaltAnswer & 1;
-
- if (HasOS85MenuMgr) {
- // load MenusLib stub for access to MenusLib
- if (!InitMenusLibInterface ()) {
- HasOS85MenuMgr = false; // if loading of stub fails, then use old technique
- }
- }
-
- // Save the global A4 register for the hook/filter functions
- PrepareCallback ();
-
- // allocate the ProcPtrs
- gNewExitToShell = NewRoutineDescriptor ((ProcPtr)quit, kPascalStackBased, GetCurrentISA());
- gNewWNE = NewRoutineDescriptor ((ProcPtr)wneHook, wneProcInfo, GetCurrentISA());
- gOldWNE = (wneProc)nil;
- gOldExitToShell = (UniversalProcPtr)nil;
-
- gCSIsHidden = gMBIsHidden = qdSet = false;
- }
-
- void PluginEntry (void)
- {
- for (int i = 0; i < pluginExportCode; ++i) {
- REALRegisterMethod (&methods[i]);
- }
- init ();
- }
-